package com.api;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.component.domain.MFile;
import com.component.service.MFileService;
import com.system.common.Result;
import com.system.util.DictiUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URLEncoder;
import java.util.List;

/**
 * @Classname MfileApi
 * @Description TODO
 * @Date 2023/9/17 13:59
 * @Created by XiongXiong
 * @Author: X.I.O
 */
@RestController
@RequestMapping("/mfile")
public class MfileApi {

    @Autowired
    private MFileService mFileService;

    @PostMapping("/scan")
    public JSONObject scanMFile(@RequestBody JSONObject jsonObject){
        if(!jsonObject.containsKey("filepath")){
            return Result.errorInfo("文件路径不得为空");
        }
        String path=jsonObject.getString("filepath");
        if(!StringUtils.isNotBlank(path)){
            return Result.errorInfo("文件路径不得为空");
        }
        mFileService.addFilesByPath(path);
        return Result.successInfo("添加成功");
    }

    @GetMapping("page")
    public JSONObject page(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                           @RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize,
                           @RequestParam(value = "keyword",required = false)String keyword){
        IPage<MFile> page=mFileService.page(pageNum, pageSize, keyword);

        return Result.successInfo("success",page);
    }

    @GetMapping("/getimageres")
    public JSONObject getImages(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                @RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize){
        List<String> types =DictiUtils.getValues("system_image_list");
        if(types.size()==0){
            return Result.errorInfo("请前往字典配置图片类型: system_image_list");
        }
        IPage<MFile> mFileIPage=mFileService.pageByFileType(pageNum,pageSize,types);
        return Result.successInfo(mFileIPage);
    }

    @GetMapping("/getvideores")
    public JSONObject getVideoRes(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                  @RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize){
        List<String> types =DictiUtils.getValues("system_video_list");
        if(types.size()==0){
            return Result.errorInfo("请前往字典配置视频类型: system_video_list");
        }
        IPage<MFile> mFileIPage=mFileService.pageByFileType(pageNum,pageSize,types);
        return Result.successInfo(mFileIPage);
    }


    /**
     * 文件下载
     * @param id
     */
    @GetMapping("donload")
    public JSONObject download(@RequestParam("id")String id, HttpServletResponse response, HttpServletRequest request) throws IOException {
        if(StringUtils.isEmpty(id)){
            return Result.errorInfo("id不得为空");
        }
        MFile mFile=mFileService.getById(id);
        if(mFile==null){
            return Result.errorInfo("文件数据已过期");
        }
        File file = new File(mFile.getFilePath());
        RandomAccessFile randomFile = new RandomAccessFile(file, "r");//只读模式
        long contentLength = randomFile.length();
        String range = request.getHeader("Range");
        int start = 0, end = 0;
        if(range != null && range.startsWith("bytes=")){
            String[] values = range.split("=")[1].split("-");
            start = Integer.parseInt(values[0]);
            if(values.length > 1){
                end = Integer.parseInt(values[1]);
            }
        }
        int requestSize = 0;
        if(end != 0 && end > start){
            requestSize = end - start + 1;
        } else {
            requestSize = Integer.MAX_VALUE;
        }
        String fileName = URLEncoder.encode(file.getName(), "UTF-8");
        response.setContentType(mFile.getFileType());
        response.setHeader("Accept-Ranges", "bytes");
        response.setHeader("ETag", file.getName());
        response.addHeader("Content-Disposition", "form-data ; filename=" + fileName );
        response.setHeader("Last-Modified",mFile.getCreateTime().toString());
        //第一次请求只返回content length来让客户端请求多次实际数据
        if(range == null){
            response.setHeader("Content-length", contentLength + "");
        }else{
            //以后的多次以断点续传的方式来返回视频数据
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//206
            long requestStart = 0, requestEnd = 0;
            String[] ranges = range.split("=");
            if(ranges.length > 1){
                String[] rangeDatas = ranges[1].split("-");
                requestStart = Integer.parseInt(rangeDatas[0]);
                if(rangeDatas.length > 1){
                    requestEnd = Integer.parseInt(rangeDatas[1]);
                }
            }
            long length = 0;
            if(requestEnd > 0){
                length = requestEnd - requestStart + 1;
                response.setHeader("Content-length", "" + length);
                response.setHeader("Content-Range", "bytes " + requestStart + "-" + requestEnd + "/" + contentLength);
            }else{
                length = contentLength - requestStart;
                response.setHeader("Content-length", "" + length);
                response.setHeader("Content-Range", "bytes "+ requestStart + "-" + (contentLength - 1) + "/" + contentLength);
            }
        }
        ServletOutputStream out = response.getOutputStream();
        int needSize = requestSize;
        randomFile.seek(start);
        while(needSize > 0){
            byte[] buffer = new byte[4096];
            int len = randomFile.read(buffer);
            if(needSize < buffer.length){
                out.write(buffer, 0, needSize);
            } else {
                out.write(buffer, 0, len);
                if(len < buffer.length){
                    break;
                }
            }
            needSize -= buffer.length;
        }
        randomFile.close();
        out.close();
        return Result.successInfo("传输完成");
    }
}
